package com.jf3q.securitydemo.config;

import com.jf3q.securitydemo.filter.ValidCodeFilter;
import com.jf3q.securitydemo.service.UserService;
import com.jf3q.securitydemo.utils.MyAccessDecisionManager;
import com.jf3q.securitydemo.utils.MyFilterInvocationSecurityMetadataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.ObjectPostProcessor;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.access.intercept.FilterSecurityInterceptor;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * @author:xiaojie
 * @create: 2024-01-28 08:30
 * @Description:
 */

@Configuration
public class SpringSecurityConf implements WebMvcConfigurer {

    @Autowired
    MyFilterInvocationSecurityMetadataSource myFilterInvocationSecurityMetadataSource;
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/toLogin").setViewName("pages/login");
    }


    @Autowired
    ValidCodeFilter validCodeFilter;

    @Autowired
    UserService userService;
    @Bean
    PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();//加盐加密  123
    }

//    @Bean
//    UserDetailsService userDetailsService(){
//        InMemoryUserDetailsManager manager= new InMemoryUserDetailsManager();
//        UserDetails user1= User.withUsername("user1").password("$2a$10$eLYO3jglHeZBOYq9eP025eoTlgOl0j0puvSwiwZNpbK/VdjXaq8X.").roles("role1").build();
//        UserDetails user2= User.withUsername("user2").password("$2a$10$aMaLfkekupu1TRWyOgVzn.k92g8XNq2ISmoqS0lXXSp.lZlELF046").roles("role2").build();
//        UserDetails user3= User.withUsername("user3").password("$2a$10$zmZ8YWzJpwjhv13jDVukUeTpIWu75QJzXlEOt4zJWUwU9.HsJPxiu").roles("role3").build();
//        manager.createUser(user1);
//        manager.createUser(user2);
//        manager.createUser(user3);
//        return manager;
//    }


    //有些页面或者接口，，游客都能访问    设置白名单

    @Bean
    WebSecurityCustomizer webSecurityCustomizer(){//放行静态资源的
        return web -> web.ignoring().requestMatchers("/webjars/**","/css/**","/js/**");
    }



    @Autowired
    MyAccessDecisionManager myAccessDecisionManager;

    //过滤器链条
    @Bean
    SecurityFilterChain securityFilterChain(HttpSecurity security) throws Exception {
        security.authorizeRequests()
                .requestMatchers("/","/loginError","/validcode","/toLogin","/login").permitAll()//匿名访问
//                .requestMatchers("/level1/**").hasRole("role1")
//                .requestMatchers("/level2/**").hasRole("role2")
//                .requestMatchers("/level3/**").hasRole("role3")

                .withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {
                    @Override
                    public <O extends FilterSecurityInterceptor> O postProcess(O object) {

                        object.setSecurityMetadataSource(myFilterInvocationSecurityMetadataSource);//访问此url需要的权限
                        object.setAccessDecisionManager(myAccessDecisionManager);//当前登陆者有没有上面需要这些权限呢
                        return object;
                    }
                })
                .anyRequest().authenticated()
                .and()
                .formLogin()
                    .defaultSuccessUrl("/",true)
                .loginPage("/toLogin")
                .loginProcessingUrl("/login")
                .failureUrl("/loginError")
                .usernameParameter("uname")
                .passwordParameter("pass")
                .and()
                .logout().logoutSuccessUrl("/")
                .and()
                .csrf().disable()
                .rememberMe()
                .and()
                .addFilterBefore(validCodeFilter, UsernamePasswordAuthenticationFilter.class);



        security.userDetailsService(userService);
        return security.build();

    }

}
